<?php

namespace common\models;

use cm;
use yii;
use yii\base\Model;

class AuthModel extends Model
{
    /**
     * 验证角色权限
     * @param $sysAppID
     * @param $accountID
     * @return bool
     */
    public function checkRoleAuth($accountID)
    {
        $accountInfo = Cm::$db->one("select is_superman from sys_account where id={$accountID}");
        $isSysManager = isset($accountInfo['is_superman']) ? $accountInfo['is_superman'] : 0;
        if ($isSysManager)
            return true;

        $route = strtolower(Yii::$app->controller->route);
        $routeArr = explode('/', $route);
        if (count($routeArr) == 3)
            $route = $routeArr[1] . '/' . $routeArr[2];

        $sql = "SELECT b.* from sys_auth_role_permissions a
INNER JOIN (

SELECT a.id,a.type,a.req_method,a.req_key,a.req_value 
from sys_auth_modules_actions_permissions a 
INNER JOIN sys_auth_modules_actions b on a.action_id=b.id
where a.module_id<>0 and a.`status`=1 and a.state=0 and b.`status`=1 and b.state=0 and b.route='{$route}'

) b on a.permissions_id=b.id
where a.role_id in (SELECT role_id from sys_account_role where account_id={$accountID})";

        $curAllPermissions = Cm::$db->all($sql);

        if (Yii::$app->request->method == "GET") {

            $flag = false;
            $routeKey = '';
            foreach ($curAllPermissions as $per) {
                if ($per['req_method'] == 'getall')
                    return true;
                if (!empty($per['req_key']) && $per['req_method'] == 'get') {
                    $routeKey = $per['req_key'];
                }
                if ($per['type'] === '0')
                    $flag = true;
            }

            if (!empty($routeKey)) {
                if (isset($_GET[$routeKey])) {
                    $flag = false;
                    $curKeyValue = $_GET[$routeKey];
                    foreach ($curAllPermissions as $per) {
                        if ($per['req_key'] == $routeKey && $per['req_value'] == $curKeyValue) {
                            $flag = true;
                        }
                    }
                }
            }
            return $flag;
        }
        if (Yii::$app->request->method == "POST") {
            $flag = false;
            $routeKey = '';
            foreach ($curAllPermissions as $per) {
                if ($per['req_method'] == 'postall')
                    return true;
                if (!empty($per['req_key']) && $per['req_method'] == 'post') {
                    $routeKey = $per['req_key'];
                }
//                if ($per['type'] === '0')
//                    $flag = true;
            }

            if (!empty($routeKey)) {
                if (isset($_GET[$routeKey])) {
                    $flag = false;
                    $curKeyValue = $_GET[$routeKey];
                    foreach ($curAllPermissions as $per) {
                        if ($per['req_key'] == $routeKey && $per['req_value'] == $curKeyValue) {
                            $flag = true;
                        }
                    }
                }
            }
            return $flag;
        }


        return false;
    }

    /**
     * 刷新系统权限
     * @param $sysAlias
     */
    public function refreshAuth($sysAlias)
    {
        $sys = Cm::$db->one("select * from sys where alias='{$sysAlias}'");
        if (!isset($sys['id']))
            Cm::$res->error('未找到应用');

        $sysID = $sys['id'];
        $sysAuths = Cm::$app->reflectionAuth()->getAllDocs(Yii::$app->params['authdoc'], $sysAlias);
        foreach ($sysAuths as $sysAuth) {

            //禁用全部应用的 module,action,permission
            Cm::$db->update('sys_auth_modules', ['state' => 1], "sys_id={$sysID}");
            Cm::$db->update('sys_auth_modules_actions', ['state' => 1], "sys_id={$sysID}");
            Cm::$db->update('sys_auth_modules_actions_permissions', ['state' => 1], "sys_id={$sysID} and type!=3");

            if (count($sysAuth['auths']) > 0) {
                foreach ($sysAuth['auths'] as $auth) {

                    $existModule = Cm::$db->one("select * from sys_auth_modules where sys_id={$sysID} and alias='{$auth['alias']}'");

                    $moduleData = array(
                        "md5" => $auth['md5'],
                        "name" => $auth['name'],
                        "remark" => $auth['remark'],
                        "sort" => $auth['sort'],
                        "state" => $auth['deprecated'] ? 1 : 0,
                    );

                    $moduleID = isset($existModule['id']) ? $existModule['id'] : '';
                    if (empty($moduleID)) {
                        $moduleData['sys_id'] = $sysID;
                        $moduleData['namespace'] = $auth['namespace'];
                        $moduleData['alias'] = $auth['alias'];
                        $moduleData['status'] = 1;
                        $moduleData['addtime'] = time();
                        $moduleID = Cm::$db->insert('sys_auth_modules', $moduleData);
                    } else {
                        Cm::$db->update('sys_auth_modules', $moduleData, "id={$moduleID}");
                    }

                    foreach ($auth['methods'] as $action) {

                        $action['deprecated'] = $auth['deprecated'] ? true : $action['deprecated'];

                        $existAction = Cm::$db->one("select * from sys_auth_modules_actions where module_id={$moduleID} and alias='{$action['alias']}'");

                        $actionData = array(
                            "md5" => $action['md5'],
                            "name" => $action['name'],
                            "type" => $action['type'],
                            "guest" => $action['guest'] ? 1 : 0,
                            "common" => $action['common'],
                            "state" => $action['deprecated'] ? 1 : 0,
                            "sort" => $action['sort'],
                            "remark" => $action['remark'],
                        );
                        $actionID = isset($existAction['id']) ? $existAction['id'] : '';
                        if (empty($actionID)) {
                            $actionData['sys_id'] = $sysID;
                            $actionData['module_id'] = $moduleID;
                            $actionData['alias'] = $action['alias'];
                            $actionData['route'] = $auth['alias'] . '/' . $action['alias'];
                            $actionData['status'] = 1;
                            $actionData['addtime'] = time();
                            $actionID = Cm::$db->insert('sys_auth_modules_actions', $actionData);
                        } else
                            Cm::$db->update('sys_auth_modules_actions', $actionData, "id={$actionID}");

                        switch ($action['common']) {
                            case 'all'://所有权限
                                break;
                            case 'get'://get所有权限，只需更新 post 相关权限
                                $this->refreshPostPermission($sysID, $moduleID, $actionID, $action);
                                break;
                            case 'post'://post所有权限，只需更新 get 相关权限
                                $this->refreshGetPermission($sysID, $moduleID, $actionID, $action);
                                break;
                            default :
                                $this->refreshGetPermission($sysID, $moduleID, $actionID, $action);
                                $this->refreshPostPermission($sysID, $moduleID, $actionID, $action);
                                break;
                        }
                    }
                }
            }
        }

        Cm::$res->susess();
    }

    public function menus($sysID, $accountID)
    {
        $accountInfo = Cm::$db->one("select is_superman from sys_account where id={$accountID}");
        $isSysManager = isset($accountInfo['is_superman']) ? $accountInfo['is_superman'] : 0;

        $sql = '';
        if (!$isSysManager) {
            $sql = "INNER JOIN (SELECT a.action_id from (SELECT id,action_id FROM `sys_auth_modules_actions_permissions` where module_id=0 and `status`=1 and state=0) a
                    INNER JOIN sys_auth_role_permissions b on a.id=b.permissions_id
                    where b.role_id in (SELECT role_id from sys_account_role where account_id={$accountID})) b on a.id=b.action_id";
        }

        $sql = "SELECT a.id,a.parent_id,a.title,a.icon,a.link,c.route 
from sys_auth_menus a {$sql} 
left JOIN sys_auth_modules_actions c on a.action_id=c.id
where a.`status`=1 and a.sys_id={$sysID} order by a.sort asc";
        $data = Cm::$db->all($sql);
        $menus = [];
        foreach ($data as $item) {
            if ($item['parent_id'] == "0") {
                $m1 = $item;
                $m1['items'] = [];
                foreach ($data as $item2) {
                    if ($item2['parent_id'] == $item['id']) {
                        $m2 = $item2;
                        $m2['items'] = [];

                        foreach ($data as $item3) {
                            if ($item3['parent_id'] == $item2['id']) {
                                $item3['items']=[];
                                $this->getLink($item3);
                                $m2['items'][] = $item3;
                            }
                        }
                        $this->getLink($m2);
                        $m1['items'][] = $m2;
                    }
                }
                $this->getLink($m1);
                $menus[] = $m1;
            }
        }
        return $menus;
    }


    //************************************************************************************//

    private function refreshGetPermission($sysID, $moduleID, $actionID, $action)
    {
        if ($action['getall']) {
//            $permissionInfo = Cm::$db->one("select * from sys_auth_modules_actions_permissions where module_id={$moduleID} and action_id={$actionID} and type=2 and req_method='getall'");
//
//            if (!$permissionInfo) {
//                $permissionInfo = array(
//                    "sys_id" => $sysID,
//                    "module_id" => $moduleID,
//                    "action_id" => $actionID,
//                    "name" => "所有权限",
//                    "type" => 2,
//                    "req_method" => "getall",
//                    "status" => 1,
//                    "state" => $action['deprecated'] ? 1 : 0,
//                    "addtime" => time()
//                );
//                Cm::$db->insert("sys_auth_modules_actions_permissions", $permissionInfo);
//            } else {
//                $perID = $permissionInfo['id'];
//                $permissionInfo = array(
//                    "state" => $action['deprecated'] ? 1 : 0
//                );
//                Cm::$db->update("sys_auth_modules_actions_permissions", $permissionInfo, "id={$perID}");
//            }
        }
        foreach ($action['get'] as $get) {
            if (empty($get['key']) || empty($get['title']))
                Cm::$res->error($action['name'] . "【{$action['alias']}】的 get 权限配置有误！");
        }

        foreach ($action['get'] as $get) {
            $permissionInfo = Cm::$db->one("select * from sys_auth_modules_actions_permissions where module_id={$moduleID} and action_id={$actionID} and type=1 and req_method='get' and req_key='{$get['key']}' and req_value='{$get['value']}'");

            if (!$permissionInfo) {
                $permissionInfo = array(
                    "sys_id" => $sysID,
                    "module_id" => $moduleID,
                    "action_id" => $actionID,
                    "name" => $get['title'],
                    "type" => 1,
                    "req_method" => "get",
                    "req_key" => $get['key'],
                    "req_value" => $get['value'],
                    "status" => 1,
                    "state" => $action['deprecated'] ? 1 : 0,
                    "addtime" => time()
                );
                Cm::$db->insert("sys_auth_modules_actions_permissions", $permissionInfo);
            } else {
                $perID = $permissionInfo['id'];
                $permissionInfo = array(
                    "state" => $action['deprecated'] ? 1 : 0,
                    "name" => $get['title']
                );
                Cm::$db->update("sys_auth_modules_actions_permissions", $permissionInfo, "id={$perID}");
            }
        }

        $_permissionInfo = Cm::$db->one("select * from sys_auth_modules_actions_permissions where module_id={$moduleID} and action_id={$actionID} and type=0");
        if (!$_permissionInfo) {
            $_permissionInfo = array(
                "sys_id" => $sysID,
                "module_id" => $moduleID,
                "action_id" => $actionID,
                "name" => "页面访问",
                "type" => 0,
                "status" => 1,
                "state" => $action['deprecated'] ? 1 : 0,
                "addtime" => time()
            );
            Cm::$db->insert("sys_auth_modules_actions_permissions", $_permissionInfo);
        } else {
            $perID = $_permissionInfo['id'];
            $_permissionInfo = array(
                "state" => $action['deprecated'] ? 1 : 0
            );
            Cm::$db->update("sys_auth_modules_actions_permissions", $_permissionInfo, "id={$perID}");
        }
    }

    private function refreshPostPermission($sysID, $moduleID, $actionID, $action)
    {
        if ($action['postall']) {
//            $permissionInfo = Cm::$db->one("select * from sys_auth_modules_actions_permissions where module_id={$moduleID} and action_id={$actionID} and type=2 and req_method='postall'");
//            if (!$permissionInfo) {
//                $permissionInfo = array(
//                    "sys_id" => $sysID,
//                    "module_id" => $moduleID,
//                    "action_id" => $actionID,
//                    "name" => "所有权限",
//                    "type" => 2,
//                    "req_method" => "postall",
//                    "status" => 1,
//                    "state" => $action['deprecated'] ? 1 : 0,
//                    "addtime" => time()
//                );
//                Cm::$db->insert("sys_auth_modules_actions_permissions", $permissionInfo);
//            } else {
//                $perID = $permissionInfo['id'];
//                $permissionInfo = array(
//                    "state" => $action['deprecated'] ? 1 : 0
//                );
//                Cm::$db->update("sys_auth_modules_actions_permissions", $permissionInfo, "id={$perID}");
//            }
        }
        foreach ($action['post'] as $get) {
            if (empty($get['key']) || empty($get['title']))
                Cm::$res->error($action['name'] . "【{$action['alias']}】的 post 权限配置有误！");
        }

        foreach ($action['post'] as $get) {
            if($get['common'])
                continue;
            $permissionInfo = Cm::$db->one("select * from sys_auth_modules_actions_permissions where module_id={$moduleID} and action_id={$actionID} and type=1 and req_method='post' and req_key='{$get['key']}' and req_value='{$get['value']}'");

            if (!$permissionInfo) {
                $permissionInfo = array(
                    "sys_id" => $sysID,
                    "module_id" => $moduleID,
                    "action_id" => $actionID,
                    "name" => $get['title'],
                    "type" => 1,
                    "req_method" => "post",
                    "req_key" => $get['key'],
                    "req_value" => $get['value'],
                    "status" => 1,
                    "state" => 0,
                    "addtime" => time()
                );
                Cm::$db->insert("sys_auth_modules_actions_permissions", $permissionInfo);
            } else {
                $perID = $permissionInfo['id'];
                $permissionInfo = array(
                    "state" => $action['deprecated'] ? 1 : 0,
                    "name" => $get['title']
                );
                Cm::$db->update("sys_auth_modules_actions_permissions", $permissionInfo, "id={$perID}");
            }
        }
    }

    private function getLink(&$row)
    {
        if (count($row['items']))
            $row['link'] = "javascript:void(0);";
        else
            if (!empty($row['route']))
                $row['link'] = yii\helpers\Url::to([$row['route']]);
    }
}